home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS02.ADF / IFF / ilbmr.c < prev    next >
Text File  |  1989-05-30  |  6KB  |  147 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMR.C  Support routines for reading ILBM files.           11/15/85
  3.  * (IFF is Interchange Format File.)
  4.  *
  5.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  6.  * This software is in the public domain.
  7.  *
  8.  * This version for the Commodore-Amiga computer.
  9.  *----------------------------------------------------------------------*/
  10. #include "iff/packer.h"
  11. #include "iff/ilbm.h"
  12.  
  13.  
  14. /* ---------- GetCMAP ------------------------------------------------*/
  15. /* pNColorRegs is passed in as a pointer to the number of ColorRegisters
  16.  * caller has space to hold.  GetCMAP sets to the number actually read.*/
  17. IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)   
  18.       GroupContext *ilbmContext;  WORD *colorMap;  UBYTE *pNColorRegs;
  19.    {
  20.    register int nColorRegs;   
  21.    register IFFP iffp;
  22.    ColorRegister colorReg;
  23.  
  24.    nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
  25.    if (*pNColorRegs < nColorRegs)   nColorRegs = *pNColorRegs;
  26.    *pNColorRegs = nColorRegs;    /* Set to the number actually there.*/
  27.  
  28.    for ( ;  nColorRegs > 0;  --nColorRegs)  {
  29.       iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg,sizeofColorRegister);
  30.       CheckIFFP();
  31.       *colorMap++ = ( ( colorReg.red   >> 4 ) << 8 ) |
  32.             ( ( colorReg.green >> 4 ) << 4 ) |
  33.             ( ( colorReg.blue  >> 4 )      );
  34.       }
  35.    return(IFF_OKAY);
  36.    }
  37.  
  38. /*---------- GetBODY ---------------------------------------------------*/
  39. /* NOTE: This implementation could be a LOT faster if it used more of the
  40.  * supplied buffer. It would make far fewer calls to IFFReadBytes (and
  41.  * therefore to DOS Read) and to movemem. */
  42. IFFP GetBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  43.       GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
  44.       BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
  45.    {
  46.    register IFFP iffp;
  47.    UBYTE srcPlaneCnt = bmHdr->nPlanes;   /* Haven't counted for mask plane yet*/
  48.    LONG srcRowBytes = RowBytes(bmHdr->w);
  49.    LONG bufRowBytes = MaxPackedSize(srcRowBytes);
  50.    int nRows = bmHdr->h;
  51.    Compression compression = bmHdr->compression;
  52.    register int iPlane, iRow, nEmpty, nFilled;
  53.    BYTE *buf, *nullDest, *nullBuf, **pDest;
  54.    BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
  55.  
  56.    if (compression > cmpByteRun1)
  57.       return(CLIENT_ERROR);
  58.  
  59.    /* Complain if client asked for a conversion GetBODY doesn't handle.*/
  60.    if ( srcRowBytes  !=  bitmap->BytesPerRow  ||
  61.          bufsize < bufRowBytes * 2  ||
  62.          srcPlaneCnt > MaxSrcPlanes )
  63.       return(CLIENT_ERROR);
  64.  
  65.    if (nRows > bitmap->Rows)
  66.       nRows = bitmap->Rows;
  67.    
  68.    /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
  69.    for (iPlane = 0; iPlane < bitmap->Depth; iPlane++)
  70.       planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
  71.    for ( ;  iPlane < MaxSrcPlanes;  iPlane++)
  72.       planes[iPlane] = NULL;
  73.  
  74.    /* Copy any mask plane ptr into corresponding "planes" slot.*/
  75.    if (bmHdr->masking == mskHasMask) {
  76.       if (mask != NULL)
  77.          planes[srcPlaneCnt] = mask;  /* If there are more srcPlanes than
  78.                * dstPlanes, there will be NULL plane-pointers before this.*/
  79.       else
  80.          planes[srcPlaneCnt] = NULL;  /* In case more dstPlanes than src.*/
  81.       srcPlaneCnt += 1;  /* Include mask plane in count.*/
  82.       }
  83.  
  84.    /* Setup a sink for dummy destination of rows from unwanted planes.*/
  85.    nullDest = buffer;
  86.    buffer  += srcRowBytes;
  87.    bufsize -= srcRowBytes;
  88.  
  89.    /* Read the BODY contents into client's bitmap.
  90.     * De-interleave planes and decompress rows.
  91.     * MODIFIES: Last iteration modifies bufsize.*/
  92.    buf = buffer + bufsize;  /* Buffer is currently empty.*/
  93.    for (iRow = nRows; iRow > 0; iRow--)  {
  94.       for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++)  {
  95.  
  96.          pDest = &planes[iPlane];
  97.  
  98.          /* Establish a sink for any unwanted plane.*/
  99.          if (*pDest == NULL) {
  100.         nullBuf = nullDest;
  101.             pDest   = &nullBuf;
  102.             }
  103.  
  104.          /* Read in at least enough bytes to uncompress next row.*/
  105.          nEmpty  = buf - buffer;      /* size of empty part of buffer.*/
  106.          nFilled = bufsize - nEmpty;      /* this part has data.*/
  107.      if (nFilled < bufRowBytes) {
  108.         /* Need to read more.*/
  109.  
  110.         /* Move the existing data to the front of the buffer.*/
  111.         /* Now covers range buffer[0]..buffer[nFilled-1].*/
  112.             movmem(buf, buffer, nFilled);  /* Could be moving 0 bytes.*/
  113.  
  114.             if (nEmpty > ChunkMoreBytes(context)) {
  115.                /* There aren't enough bytes left to fill the buffer.*/
  116.                nEmpty = ChunkMoreBytes(context);
  117.                bufsize = nFilled + nEmpty;  /* heh-heh */
  118.                }
  119.  
  120.         /* Append new data to the existing data.*/
  121.             iffp = IFFReadBytes(context, &buffer[nFilled], nEmpty);
  122.             CheckIFFP();
  123.  
  124.             buf     = buffer;
  125.         nFilled = bufsize;
  126.         nEmpty  = 0;
  127.         }
  128.  
  129.          /* Copy uncompressed row to destination plane.*/
  130.          if (compression == cmpNone) {
  131.             if (nFilled < srcRowBytes)  return(BAD_FORM);
  132.         movmem(buf, *pDest, srcRowBytes);
  133.         buf    += srcRowBytes;
  134.             *pDest += srcRowBytes;
  135.             }
  136.      else
  137.          /* Decompress row to destination plane.*/
  138.             if ( UnPackRow(&buf, pDest, nFilled,  srcRowBytes) )
  139.                     /*  pSource, pDest, srcBytes, dstBytes  */
  140.                return(BAD_FORM);
  141.          }
  142.       }
  143.  
  144.    return(IFF_OKAY);
  145.    }
  146.  
  147.